package com.spring.theory.mvc;

import static com.spring.theory.constant.GeneralConstant.LOG_INFO;

import com.spring.theory.mvc.adapter.MyRequestMappingHandlerAdapter;

import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * TestDispatcher
 *
 * @author H
 * @version 1.0
 * @date 2024-01-11 14:54
 */
@Slf4j
public class TestDispatcher {

    public static void main(String[] args) throws Exception {
        AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
        RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> methodMap = handlerMapping.getHandlerMethods();
        log.info(LOG_INFO + "handlerMapping路径与控制器的信息");
        methodMap.forEach((k, v) -> log.info(k + "==>" + v));
        log.info(LOG_INFO);

        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test4");
        request.setParameter("name", "name-aaa");
        request.addHeader("token", "token-aaa");
        MockHttpServletResponse response = new MockHttpServletResponse();
        //获取请求的控制器方法 返回处理器执行链对象（包含了处理器方法及拦截器等）
        HandlerExecutionChain chain = handlerMapping.getHandler(request);
        log.info("handler chain:{}", chain);
        //handlerAdapter作用：调用控制器方法
        MyRequestMappingHandlerAdapter handlerAdapter = context.getBean(MyRequestMappingHandlerAdapter.class);
        handlerAdapter.invokeHandlerMethod(request, response, (HandlerMethod) chain.getHandler());

        //handlerAdapter内可用于解析注解的参数解析器
        List<HandlerMethodArgumentResolver> argumentResolvers = handlerAdapter.getArgumentResolvers();
        //handlerAdapter内的返回值解析器
        List<HandlerMethodReturnValueHandler> returnValueHandlers = handlerAdapter.getReturnValueHandlers();

        //日志记录响应结果
        String str = new String(response.getContentAsByteArray(), "UTF-8");
        log.info("response:{}", str);

    }

}
